#include "ifftgpu.h"

#include "primes.h"
#include "dims.h"

using namespace std;

// Plan Creation (i.e. Solver) Codes

const CodeletInfo DIRSolver::codeletTab[] = {
    {2},
    {3},
    {4},
    {5},
    {6},
    {7},
    {8},
    {16},
    {32},
    {64},
    {NULL}
};

DIRSolver::DIRSolver() : Solver()
{
    
}

DIRSolver::~DIRSolver()
{
}

bool DIRSolver::applicable(Problem * prob, CodeletInfo * &pcode)
{
    if (prob->fftDim.size() != 1) return false;

    CodeletInfo * pcode_begin = (CodeletInfo *)codeletTab;
    for (int i=0; (pcode = pcode_begin + i)->n; i++) {
        if (pcode->n == prob->fftDim[0]) break; 
    }

    return (pcode->n > 0);
}


Plan * DIRSolver::make_plan(Problem * prob)
{
    DIRPlan * p = NULL;
    CodeletInfo * pcode = NULL;

    if (!applicable(prob, pcode)) {
        return NULL;
    }

    p = new DIRPlan();
    p->twParam = prob->twParam;
    p->iDim = prob->iDim;
    p->oDim = prob->oDim;
    p->fftDim = prob->fftDim[0];

    p->pass = 1;
    p->cost = 1;

    return p;
}

// Plan Solving Codes

DIRPlan::DIRPlan() : Plan() 
{
    twParam.n1 = 0;
    twParam.n2 = 0;
    twParam.stride = 0;

    iDim.clear();
    oDim.clear();
    fftDim = 0;
}

DIRPlan::~DIRPlan()
{
// Unload program
    iDim.clear();
    oDim.clear();
}


void DIRPlan::awake(Wakefulness w)
{
// Build IL
// Load Program
    return;
}

void DIRPlan::print(FILE *fp, int indent) 
{
    for (; indent > 0; indent--)
        fprintf(fp, "    ");

    list<Dim>::iterator i;

    fprintf(fp, "(dft-direct-%d I:",
        fftDim);
    for (i = iDim.begin(); i != iDim.end(); i++) {
        fprintf(fp, "(%d,%d)", i->n, i->stride);
    }
    fprintf(fp, " O:");
    for (i = oDim.begin(); i != oDim.end(); i++) {
        fprintf(fp, "(%d,%d)", i->n, i->stride);
    }
    fprintf(fp, " ) \n");

    return;
}

void DIRPlan::solve()
{
    return;
}